package org.ztr.yanai.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.ztr.yanai.blog.constant.MessageConstants;
import org.ztr.yanai.blog.dto.CreatePostDTO;
import org.ztr.yanai.blog.dto.PageRequestDTO;
import org.ztr.yanai.blog.dto.UpdatePostDTO;
import org.ztr.yanai.blog.entity.Post;
import org.ztr.yanai.blog.enums.PostStatusEnum;
import org.ztr.yanai.blog.exception.BusinessException;
import org.ztr.yanai.blog.exception.ErrorCode;
import org.ztr.yanai.blog.mapper.PostMapper;
import org.ztr.yanai.blog.service.PostService;
import org.ztr.yanai.blog.utils.ValidationUtil;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author: ZhaoTR
 * @Date: Created in 2025/11/22 14:30
 * @Description: 文章服务实现类
 * @Version: 1.0
 */
@Slf4j
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "post", allEntries = true)
    public Post createPost(CreatePostDTO createPostDTO) {
        // 参数校验
        if (ValidationUtil.isEmpty(createPostDTO.getTitle())) {
            throw new BusinessException(ErrorCode.POST_TITLE_EMPTY);
        }
        if (ValidationUtil.isEmpty(createPostDTO.getContent())) {
            throw new BusinessException(ErrorCode.POST_CONTENT_EMPTY);
        }

        // 创建文章
        Post post = new Post();
        post.setTitle(createPostDTO.getTitle());
        post.setContent(createPostDTO.getContent());
        post.setStatus(createPostDTO.getStatus());
        // TODO: 从当前登录用户获取userId
        // post.setUserId(getCurrentUserId());
        post.setViews(0);
        post.setLikes(0);
        post.setCreatedAt(LocalDateTime.now());
        post.setUpdatedAt(LocalDateTime.now());

        if (!save(post)) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED, MessageConstants.Post.CREATE_SUCCESS);
        }

        log.info("创建文章成功: postId={}, title={}", post.getId(), post.getTitle());
        return post;
    }

    @Override
    public boolean createPost(Post post) {
        post.setCreatedAt(LocalDateTime.now());
        post.setUpdatedAt(LocalDateTime.now());
        return save(post);
    }

    @Override
    @CacheEvict(value = "post", key = "#id")
    public void deletePostById(Long id) {
        Post post = getById(id);
        if (post == null) {
            throw new BusinessException(ErrorCode.POST_NOT_FOUND);
        }
        if (!removeById(id)) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED, MessageConstants.Post.DELETE_SUCCESS);
        }
        log.info("删除文章成功: postId={}", id);
    }

    @Override
    @Cacheable(value = "post", key = "#id")
    public Post getPostById(Long id) {
        Post post = getById(id);
        if (post == null) {
            throw new BusinessException(ErrorCode.POST_NOT_FOUND);
        }
        return post;
    }

    @Override
    public Post getPostByIdWithAuthor(Long id) {
        Post post = getPostById(id);
        // 增加浏览量
        increaseViews(id);
        // TODO: 查询作者信息并设置到post中
        return post;
    }

    @Override
    public Page<Post> listPostsByPage(PageRequestDTO pageRequest, PostStatusEnum status) {
        Page<Post> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        
        return lambdaQuery()
                .like(ValidationUtil.isNotEmpty(pageRequest.getKeyword()), 
                      Post::getTitle, pageRequest.getKeyword())
                .or()
                .like(ValidationUtil.isNotEmpty(pageRequest.getKeyword()), 
                      Post::getContent, pageRequest.getKeyword())
                .eq(status != null, Post::getStatus, status)
                .orderByDesc(Post::getCreatedAt)
                .page(page);
    }

    @Override
    public Page<Post> listPostsByPage(int pageNum, int pageSize, QueryWrapper<Post> wrapper) {
        Page<Post> page = new Page<>(pageNum, pageSize);
        return page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "post", key = "#updatePostDTO.id")
    public Post updatePostInfo(UpdatePostDTO updatePostDTO) {
        if (updatePostDTO.getId() == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "文章ID不能为空");
        }

        Post existPost = getById(updatePostDTO.getId());
        if (existPost == null) {
            throw new BusinessException(ErrorCode.POST_NOT_FOUND);
        }

        // 更新字段
        if (ValidationUtil.isNotEmpty(updatePostDTO.getTitle())) {
            existPost.setTitle(updatePostDTO.getTitle());
        }
        if (ValidationUtil.isNotEmpty(updatePostDTO.getContent())) {
            existPost.setContent(updatePostDTO.getContent());
        }
        if (updatePostDTO.getStatus() != null) {
            existPost.setStatus(updatePostDTO.getStatus());
        }
        existPost.setUpdatedAt(LocalDateTime.now());

        if (!updateById(existPost)) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED, MessageConstants.Post.UPDATE_SUCCESS);
        }

        log.info("更新文章成功: postId={}", existPost.getId());
        return existPost;
    }

    @Override
    public boolean updatePost(Post post) {
        post.setUpdatedAt(LocalDateTime.now());
        return updateById(post);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "post", allEntries = true)
    public void batchUpdatePostStatus(List<Long> postIds, PostStatusEnum status) {
        if (postIds == null || postIds.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "文章ID列表不能为空");
        }

        boolean success = lambdaUpdate()
                .in(Post::getId, postIds)
                .set(Post::getStatus, status)
                .set(Post::getUpdatedAt, LocalDateTime.now())
                .update();

        if (!success) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED, "批量更新状态失败");
        }
        log.info("批量更新文章状态成功: postIds={}, status={}", postIds, status);
    }

    @Override
    public boolean increaseViews(Long postId) {
        return lambdaUpdate()
                .eq(Post::getId, postId)
                .setSql("views = views + 1")
                .update();
    }
}
